<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Core
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-06-01
 ***********************************************************************/
if(defined("IVANENGINE_CORE_IO_SESSIONSTORAGE"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_IO_SESSIONSTORAGE", true);

require_once(dirname(__FILE__).'/Storage.php');

class CSessionStorage extends CStorage
{
    const OT_AutoStart              = 'OT_AutoStart';
    const OT_Session_ID             = 'OT_Session_ID';
    const OT_Session_Name           = 'OT_Session_Name';
    const OT_Session_Cookie_Lifetime= 'OT_Session_Cookie_Lifetime';
    const OT_Session_Cookie_Path    = 'OT_Session_Cookie_Path';
    const OT_Session_Cookie_Domain  = 'OT_Session_Cookie_Domain';
    const OT_Session_Cookie_Secure  = 'OT_Session_Cookie_Secure';
    const OT_Session_Cookie_HttpOnly= 'OT_Session_Cookie_HttpOnly';
    const OT_Session_Cookie_Limiter = 'OT_Session_Cookie_Limiter';
    static protected $m_this        = null;
    static protected
        $m_sessionIdRegenerated     = false,
        $m_sessionStarted           = false;
    
    public function __construct() 
    {
        parent::__construct();
    }
    
    public function __destruct() 
    {
        parent::__destruct();
    }
    
    static public function Get()
    {
        if( self::$m_this == null )
        {
            parent::StartSingleton();
            self::$m_this = new CSessionStorage();
            parent::EndSingleton();
        }
        return self::$m_this;
    }
    
    public function Initialize($options = array())
    {
        $cookieDefaults = session_get_cookie_params();
        
        $options = array_merge(array(
            self::OT_Session_Name           => 'IvanEngine',
            self::OT_Session_ID             => null,
            self::OT_AutoStart              => true,
            self::OT_Session_Cookie_Lifetime=> $cookieDefaults['lifetime'],
            self::OT_Session_Cookie_Path    => $cookieDefaults['path'],
            self::OT_Session_Cookie_Domain  => $cookieDefaults['domain'],
            self::OT_Session_Cookie_Secure  => $cookieDefaults['secure'],
            self::OT_Session_Cookie_HttpOnly=> isset($cookieDefaults['httponly']) ? $cookieDefaults['httponly'] : false,
            self::OT_Session_Cookie_Limiter => 'none',
        ), $options);
        
        parent::Initialize($options);
        
        // set session name
        $sessionName = $this->m_options[self::OT_Session_Name];
        session_name($sessionName);

        if (!(boolean) ini_get('session.use_cookies') && $sessionId = $this->m_options[self::OT_Session_ID])
        {
            session_id($sessionId);
        }

        $lifetime = $this->m_options[self::OT_Session_Cookie_Lifetime];
        $path     = $this->m_options[self::OT_Session_Cookie_Path];
        $domain   = $this->m_options[self::OT_Session_Cookie_Domain];
        $secure   = $this->m_options[self::OT_Session_Cookie_Secure];
        $httpOnly = $this->m_options[self::OT_Session_Cookie_HttpOnly];
        session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly);

        if (!is_null($this->m_options[self::OT_Session_Cookie_Limiter]))
        {
            session_cache_limiter($this->m_options[self::OT_Session_Cookie_Limiter]);
        }

        if ($this->m_options[self::OT_AutoStart] && !self::$m_sessionStarted)
        {
            session_start();
            self::$m_sessionStarted = true;
        }
    }
    
    public function Read($key)
    {
        $retval = null;

        if (isset($_SESSION[$key]))
        {
            $retval = $_SESSION[$key];
        }

        return $retval;
    }

    public function Remove($key)
    {
        $retval = null;
        if (isset($_SESSION[$key]))
        {
            $retval = $_SESSION[$key];
            unset($_SESSION[$key]);
        }
        return $retval;
    }

    public function Write($key, $data)
    {
        $_SESSION[$key] = $data;
    }

    public function Regenerate($destroy = false)
    {
        if (self::$m_sessionIdRegenerated)
        {
            return;
        }

        // regenerate a new session id once per object
        session_regenerate_id($destroy);

        self::$m_sessionIdRegenerated = true;
    }

    public function Shutdown()
    {
        // don't need a shutdown procedure because read/write do it in real-time
        session_write_close();
    }
}
?>
